# trade_executor.py - 专门处理交易执行逻辑
import asyncio
import json
from typing import Dict

from redis import Redis
from sqlalchemy.ext.asyncio import AsyncSession

from config.env import RedisConfig
from module_stock.entity.vo.trade_vo import TradeModel, UpdateTradeStatusModel
from module_stock.service.trade_service import TradeService


class TradeExecutor:
    """交易执行器 - 负责监控行情并执行交易"""

    def __init__(self, db_session: AsyncSession, redis: Redis = None):
        self.db_session = db_session
        # 创建自己的同步Redis连接
        self.redis = Redis(
            host=RedisConfig.redis_host,
            port=RedisConfig.redis_port,
            username=RedisConfig.redis_username,
            password=RedisConfig.redis_password,
            db=RedisConfig.redis_database,
            encoding='utf-8',
            decode_responses=True,
        )
        self.is_running = False

    async def start(self):
        """启动交易执行器"""
        if not self.is_running:
            self.is_running = True
            print("交易执行器已启动")

    async def stop(self):
        """停止交易执行器"""
        if self.is_running:
            self.is_running = False
            print("交易执行器已停止")

    def get_status(self):
        return self.is_running

    def on_tick_data(self, data: Dict):
        """行情数据回调处理"""
        # 回调参数stock_datas格式为 { stock_code : [data1, data2, ...] }
        if not self.is_running:
            return
        print(f"on_tick_data: {data}")
        # 检查是否有监控中的交易任务达到了交易条件
        for stock_code, data_list in data.items():
            if not data_list:
                continue
            stock_data = data_list[0]
            last_price = stock_data.get("lastPrice")
            related_trade_tasks = self.get_trade_tasks_from_redis(stock_code)
            print(f"获取股票{stock_code}的交易任务列表: {related_trade_tasks}")
            for task in related_trade_tasks:
                print(f'比较价格:{stock_code} - [交易价 : {task.price}] : [现价 : {last_price}]')
                # 交易任务为买入，且当前价格低于等于目标价格
                if task.direction == '1' and last_price <= float(task.price):
                    print(f'执行买入:{stock_code} - {task.price}')
                    # TODO:有推送时可测试
                    asyncio.create_task(TradeService.update_trade_status_services(self.redis, self.db_session,
                                                                                  UpdateTradeStatusModel(id=task.id,
                                                                                                         status="3")))
                elif task.direction == '2' and last_price >= float(task.price):
                    print(f'执行卖出:{stock_code} - {task.price}')
                    asyncio.create_task(TradeService.update_trade_status_services(self.redis, self.db_session,
                                                                                  UpdateTradeStatusModel(id=task.id,
                                                                                                         status="3")))

    def get_trade_tasks_from_redis(self, stock_code: str):
        """从redis中获取指定股票代码的交易任务列表"""
        redis_key = f"trade_tasks:{stock_code}"
        # 使用同步方法直接获取数据
        tasks_data = self.redis.lrange(redis_key, 0, -1)
        print(f"获取股票{stock_code}的交易任务列表: {tasks_data}")
        related_trade_tasks = []
        for task_data in tasks_data:
            task_dict = json.loads(task_data)
            task = TradeModel(**task_dict)
            related_trade_tasks.append(task)
        return related_trade_tasks


# 全局交易执行器实例
_trade_executor = None


def init_trade_executor(db_session: AsyncSession, redis: Redis = None):
    """初始化交易执行器单例"""
    global _trade_executor
    if _trade_executor:
        return
    _trade_executor = TradeExecutor(db_session, redis)


def get_trade_executor() -> TradeExecutor:
    """获取交易执行器单例"""
    global _trade_executor
    if _trade_executor is None:
        raise RuntimeError("TradeExecutor not initialized")
    return _trade_executor  # type: ignore
